﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Checkers.Sever.DBModule.databaseProxy
{
    public class clsDatabaseUtility : IDatabaseUtility
    {
        private static CheckersDBDiagramDataContext _dbContext;
        private static clsDatabaseUtility utility;

        public clsDatabaseUtility() 
        {
            _dbContext = new CheckersDBDiagramDataContext();
            
        }

        public static clsDatabaseUtility getInstance() 
        {
            if(utility == null)
            {
                utility = new clsDatabaseUtility();
            }

            return utility;
        }

        public Player AddPlayerProfile(string name, string username, string password)
        {
            var player = new Player()
            {
                playerName = name,
                playerPassword = password,
                playerUsername = username
            };

            _dbContext.Players.InsertOnSubmit(player);
            _dbContext.SubmitChanges();

            return player;
        }

        public Player AuthenticatePlayer(string username, string password)
        {
            var objPlayerList = from player in _dbContext.Players where player.playerUsername == username && player.playerPassword == password select player;
            var objPlayer = objPlayerList.ToList().First();

            return objPlayer;
        }

        public IList<Player> GetPlayersList()
        {
            IList<Player> list = new List<Player>();
            var objPlayerList = from player in _dbContext.Players select player;
            list = objPlayerList.ToList();
            return list;
        }

        public IList<GameRoom> GetGameRooms()
        {
            
            var objGameRoomList = from gameroom 
                                      in _dbContext.GameRooms 
                                  select gameroom;
            return objGameRoomList.ToList();
            
        }

        public IList<GameRoomClient> GetGameRoomSubscribers(long objGameRoomId)
        {
            
            var objGameRoomClientList = from gameroomclient 
                                            in _dbContext.GameRoomClients 
                                        where gameroomclient.gameId == objGameRoomId 
                                        select gameroomclient;
            return objGameRoomClientList.ToList();
            
        }

        public IList<GameMove> GetGameMovesSortedByTimeStamp(long objGameRoomId)
        {
            var objGameMoveList = from gameMove 
                                      in _dbContext.GameMoves 
                                  where gameMove.gameId == objGameRoomId 
                                  orderby gameMove.timestamp descending 
                                  select gameMove;
            return objGameMoveList.ToList();
        }


        public IList<GameMove> GetLatestGameMoves(long objGameRoomId, DateTime timestamp)
        {
            var objGameMoveList = from gameMove 
                                      in _dbContext.GameMoves 
                                  where gameMove.gameId == objGameRoomId 
                                  && gameMove.timestamp > timestamp 
                                  orderby timestamp descending 
                                  select gameMove;
            return objGameMoveList.ToList();
        }


        

        public GameRoom CreateGameRoom(int playerUserId)
        {
            var objGameRoom = new GameRoom()
            {
                gameStatus = 0,
                timestamp = DateTime.Now,
                isOccupiedBy = 0
            };

            _dbContext.GameRooms.InsertOnSubmit(objGameRoom);


            //obj room client add
            var objGameRoomClient = new GameRoomClient()
            {
                playerId = playerUserId,
                playerType = 0,
                gameId = objGameRoom.gameId
            };

            objGameRoom.GameRoomClients.Add(objGameRoomClient);
            //_dbContext.GameRoomClients.InsertOnSubmit(objGameRoomClient);

            _dbContext.SubmitChanges();

            return objGameRoom;
        }


        public GameRoom JoinGameRoom(int playerUserId, int gameId, int playerMode)
        {
            //obj room client add
            var objGameRoomClient = new GameRoomClient()
            {
                playerId = playerUserId,
                playerType = playerMode,
                gameId = gameId
            };

            _dbContext.GameRoomClients.InsertOnSubmit(objGameRoomClient);

            return objGameRoomClient.GameRoom;
        }


        public GameRoom UpdateGameRoomStatus(int gameId, int status)
        {
            var gameRoomList = from room in _dbContext.GameRooms where room.gameId == gameId select room;

            var gameRoomObj = gameRoomList.First();
            gameRoomObj.gameStatus = status;

            _dbContext.SubmitChanges();

            return gameRoomObj;
        }





        public GameMove AddMove(int playerId, int gameId, string pieceId, int finalPosition, DateTime? timestamp, string listOfRemovedPieces, bool isKing)
        {
            var move = new GameMove()
            {
                gameId = gameId,
                playerId = playerId,
                pieceId = pieceId,
                finalPositionPanelId = finalPosition,
                
                timestamp = timestamp,
                listOfRemovedPieces = listOfRemovedPieces,
                isKing = isKing
            };

            _dbContext.GameMoves.InsertOnSubmit(move);

            _dbContext.SubmitChanges();

            return move;
        }

        public GameRoom GetOccupiedStatusOfGameRoom(int gameId, int occupiedByPLayer)
        {
            var objGameRoom = from room in _dbContext.GameRooms where room.gameId == gameId select room;
            return objGameRoom.First();
        }

        public GameRoom UpdateOccupiedStatusOfGameRoom(int gameId, int occupiedByPLayer)
        {
            var objGameRoomList = from room in _dbContext.GameRooms where room.gameId == gameId select room;
            var objGameRoom = objGameRoomList.First();

            objGameRoom.isOccupiedBy = occupiedByPLayer;
            
            _dbContext.SubmitChanges();

            return objGameRoom;
        }


        public IList<GameMove> CheckForWinnerStatus(int gameId) 
        {
            var gameMoves = from move in _dbContext.GameMoves where move.gameId == gameId && move.listOfRemovedPieces != "" select move ;

            return gameMoves.ToList();
        }

        public Winner AddWinnerToGame(int gameId, int playerId) 
        {
            var gameWinner = new Winner()
            {
                gameId = gameId,
                playerId = playerId,
            };


            _dbContext.Winners.InsertOnSubmit(gameWinner);
            _dbContext.SubmitChanges();

            return gameWinner;
        }


        public Winner GetWinner(int gameId) 
        {
            var gameWinner  = from winner in _dbContext.Winners where winner.gameId == gameId select winner;
            if(gameWinner.Count() == 0)
            {
                return null;
            }

            return gameWinner.First();
        }
    }
}
 